package ioc

import (
	"context"
	"fmt"
	grpc2 "gitee.com/xiao_hange/go-admin-log/log/grpc"
	"gitee.com/xiao_hange/go-admin-log/log/ioc/config"
	config2 "gitee.com/xiao_hange/go-admin-log/log/ioc/config"
	"gitee.com/xiao_hange/go-admin-pkg/pkg/grpcx"
	"gitee.com/xiao_hange/go-admin-pkg/pkg/grpcx/trace"
	"gitee.com/xiao_hange/go-admin-pkg/pkg/logger"
	"google.golang.org/grpc"
	"time"
)

// 注意 InitGrpcServer(filev1 *grpc2.FileServiceServer) 要使用指针  要和 NewInitGrpcServer 返回保持一样

func InitGrpcServer(logv1 *grpc2.LogServiceServer, l logger.AppLogger, cfg *config.ServerConfig, ja *config.JaegerConfig) *grpcx.Server {
	tracerProvider := InitOTELTracerProvider((*config2.JaegerConfig)(ja))
	otelBuilder := trace.NewOTELInterceptorBuilder("file-grpc-server", tracerProvider.Tracer("log-grpc-server"), nil)
	server := grpc.NewServer(
		grpc.ChainUnaryInterceptor(
			otelBuilder.BuildUnaryServerInterceptor(),
			NewLogInterceptor(cfg.Port),
		),
	)
	logv1.Register(server)
	return &grpcx.Server{
		Server:      server,
		Port:        cfg.Port,
		Name:        "log",
		L:           l,
		ConsulAddrs: cfg.ConsulAddr,
		Weight:      cfg.Weight,
		Label:       cfg.Label,
		ServerName:  "Go-Admin-Log",
		//IpOrServerName: cfg.ServerName,
	}
}
func NewLogInterceptor(port int) grpc.UnaryServerInterceptor {
	return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
		startTime := time.Now()
		resp, err = handler(ctx, req)
		if info.FullMethod != "/grpc.health.v1.Health/Check" {
			fmt.Printf("GRPC Server[端口:%d]: 收到的请求-方法: %s,收到的请求-参数:%s,请求处理时间: %.6f秒\n", port, info.FullMethod, extractArgs(req), time.Since(startTime).Seconds())
		}
		return
	}
}
func extractArgs(req interface{}) string {
	if redacter, ok := req.(Redacter); ok {
		return redacter.Redact()
	}
	if stringer, ok := req.(fmt.Stringer); ok {
		return stringer.String()
	}
	return fmt.Sprintf("%+v", req)
}

// Redacter defines how to log an object
type Redacter interface {
	Redact() string
}
